<!--
Copyright Yahoo Inc.
SPDX-License-Identifier: Apache-2.0
-->
<template>
  <div class="d-flex align-center">
    <v-btn
      class="mr-1 skinny-search-row-btn"
      tabindex="-1"
      color="secondary"
      :style="btnStyle">
      <v-icon
        icon="mdi-menu-down"
        size="large" />
      <v-menu
        activator="parent"
        location="bottom">
        <v-card>
          <v-list class="d-flex flex-column">
            <template v-if="currentItype === 'domain'">
              <v-btn
                @click="snapTo(0)"
                text="Registration Date"
                variant="text"
                class="justify-start" />
              <v-divider class="my-1" />
            </template>

            <v-btn
              v-for="nDays in [1, 2, 3, 7, 14, 30, -1]"
              :key="nDays"
              class="justify-start"
              @click="snapTo(nDays)"
              variant="text"
              :label="(nDays === -1) ? 'All' : `${nDays}`">
              <span v-if="nDays === -1">All</span>
              <span v-else-if="nDays === 1">1 Day</span>
              <span v-else>{{ nDays }} Days</span>
            </v-btn>
          </v-list>
        </v-card>
      </v-menu>
    </v-btn>

    <v-text-field
      variant="outlined"
      label="Start"
      class="mr-1"
      :class="[inputClass]"
      type="text"
      tabindex="0"
      ref="startDateRef"
      id="startDateField"
      v-model="localStartDate"
      :style="`width:${inputWidth}`"
      placeholder="Start Date"
      v-focus="getFocusStartDate"
      @keyup.up="startKeyUp(1)"
      @keyup.down="startKeyUp(-1)"
      @change="updateStopStart('startDate')" />
    <short-cut-tooltip
      target-id="startDateField"
      location="center">
      T
    </short-cut-tooltip>
    <v-text-field
      variant="outlined"
      label="End"
      class="mr-1"
      :class="[inputClass]"
      type="text"
      tabindex="0"
      placeholder="Stop Date"
      v-model="localStopDate"
      :style="`width:${inputWidth}`"
      @keyup.up="stopKeyUp(1)"
      @keyup.down="stopKeyUp(-1)"
      @change="updateStopStart('stopDate')" />
    <span class="text-no-wrap">
      <v-icon
        icon="mdi-help-circle-outline"
        id="timerange-input-help" />
      <html-tooltip
        :html="placeHolderTip"
        target-id="timerange-input-help" />
      <span class="pl-1">
        {{ timeRangeInfo.numDays }} days | {{ timeRangeInfo.numHours }} hours
      </span>
    </span>
  </div>
</template>

<script setup>
import HtmlTooltip from '@common/HtmlTooltip.vue';
import ShortCutTooltip from '@/utils/ShortCutTooltip.vue';
import Focus from '@common/Focus.vue';
import { parseSeconds } from '@common/vueFilters.js';
import { useStore } from 'vuex';
import { useRoute, useRouter } from 'vue-router';
import { useGetters } from '@/vue3-helpers';
import { ref, computed, onMounted, watch } from 'vue';

/**
 * -- TimeRangeInput --
 * This component handles changing a start/stop date via inputs, while managing the startDate/stopDate query params
 */

// expose as v-focus through Composition Api
const VFocus = Focus;

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({ startDate: '', stopDate: '' })
  },
  placeHolderTip: { // (Question mark hover text) -- shape of { title: String }
    type: Object,
    required: true
  },
  inputGroupSize: {
    type: String,
    default: 'xs'
  },
  inputWidth: {
    type: String,
    default: '138px'
  }
});

const inputClass = computed(() => props.inputGroupSize === 'xs' ? 'tiny-input' : 'medium-input');
const btnStyle = computed(() => props.inputGroupSize === 'xs' ? 'height: 32px !important;' : '');

const timeRangeInfo = defineModel({ required: false, default: () => ({}), type: Object });

const localStartDate = ref(timeRangeInfo.value.startDate);
const localStopDate = ref(timeRangeInfo.value.stopDate);
const startDateRef = ref(null);

const store = useStore();
const { getFocusStartDate, getActiveIndicator, getResults } = useGetters(store);

const route = useRoute();
const router = useRouter();

const currentItype = computed(() => getActiveIndicator.value?.itype);
const doneLoading = computed(() => store.state.loading.done);

function snapTo (days) {
  // always update the stop date to now
  const date = new Date();
  localStopDate.value = date.toISOString().slice(0, -5) + 'Z';
  updateStopStart('stopDate');
  localStorage.setItem('snapTo', days);

  if (days && days > 0) { // update start date to <days> ago
    const startMs = date.setDate(date.getDate() - days);
    localStartDate.value = new Date(startMs).toISOString().slice(0, -5) + 'Z';
    updateStopStart('startDate');
  } else if (days === -1) { // update start date to epoch
    localStartDate.value = new Date(0).toISOString().slice(0, -5) + 'Z';
    updateStopStart('startDate');
  } else { // update start date to registration date if it exists
    if (currentItype.value === 'domain' && getResults.value?.domain?.[getActiveIndicator.value?.query]?.['PT Whois']?.registered) {
      localStartDate.value = getResults.value.domain[getActiveIndicator.value.query]['PT Whois'].registered;
      updateStopStart('startDate');
    }
  }
}
function startKeyUp (days) {
  const date = new Date(localStartDate.value);
  const startMs = date.setDate(date.getDate() + days);
  localStartDate.value = new Date(startMs).toISOString().slice(0, -5) + 'Z';
  updateStopStart('startDate');
}
function stopKeyUp (days) {
  const date = new Date(localStopDate.value);
  const stopMs = date.setDate(date.getDate() + days);
  localStopDate.value = new Date(stopMs).toISOString().slice(0, -5) + 'Z';
  updateStopStart('stopDate');
}
function updateStopStart (updated) {
  let startMs = new Date(localStartDate.value).getTime();
  let stopMs = new Date(localStopDate.value).getTime();

  // test for relative times
  if (isNaN(startMs)) {
    startMs = parseSeconds(localStartDate.value) * 1000;
  }
  if (isNaN(stopMs)) {
    stopMs = parseSeconds(localStopDate.value) * 1000;
  }

  // can't do anything if we can't calculate the date ms
  if (isNaN(stopMs) || isNaN(startMs)) { return; }

  const updatedDate = updated === 'startDate' ? localStartDate.value : localStopDate.value;
  // update the query params with the updated value
  if (route.query[updated] !== updatedDate) {
    const query = { ...route.query };
    query[updated] = updatedDate;
    router.push({ query });
  }

  const days = (stopMs - startMs) / (3600000 * 24);

  switch (updated) {
  case 'stopDate':
    localStartDate.value = new Date(stopMs - (3600000 * 24 * days)).toISOString().slice(0, -5) + 'Z';
    localStopDate.value = new Date(stopMs).toISOString().slice(0, -5) + 'Z';
    break;
  case 'startDate':
    localStartDate.value = new Date(startMs).toISOString().slice(0, -5) + 'Z';
    break;
  }

  timeRangeInfo.value = { // syncs time range data with parent
    numDays: Math.round(days),
    numHours: Math.round(days * 24),
    startDate: localStartDate.value,
    stopDate: localStopDate.value,
    startMs,
    stopMs
  };
}

onMounted(() => {
  // set the stop/start date to the query parameters
  if (route.query.stopDate) {
    localStopDate.value = route.query.stopDate;
    updateStopStart('stopDate');
  }
  if (route.query.startDate) {
    localStartDate.value = route.query.startDate;
    updateStopStart('startDate');
  }
});

watch(getFocusStartDate, (val) => {
  if (val) { startDateRef.value?.select(); }
});

watch(doneLoading, (val) => { // snap to the last snapTo value if it exists
  if (val && localStorage.getItem('snapTo')) {
    snapTo(parseInt(localStorage.getItem('snapTo')));
  }
});
</script>
